from __future__ import division

import os.path
import pygame
from settings import settings
from graphics import graphics, request_replace
from collision import Rect

class Filmstrip:
	minimum_spacing = 10
	
	def __init__(self, menu, rect, *items):
		self.rect = rect
		self.items = items
		
		self.offset = 0
		self.true_width = self.rect.width
		
		self._adjust_item_rects()
	
	def update(self):
		for item in self.items:
			item.update()
		
		x, y = pygame.mouse.get_pos()
		
		if self.rect.collidepoint((x, y)):
			if x >= self.rect.left or x <= self.rect.right:
				left = self.rect.left + self.rect.width // 4
				right = self.rect.right - self.rect.width // 4
				
				if x <= left:
					factor = (left - x) / (self.rect.width / 2)
				elif x >= right:
					factor = (right - x) / (self.rect.width / 2)
				else:
					factor = 0
				
				self.scroll(factor * 10)
	
	def draw(self, surface):
		#surface.fill((0, 0, 0), self.rect)
		
		for item in self.items:
			item.draw(surface)
	
	def event(self, event):
		if event.type == pygame.MOUSEBUTTONDOWN:
			if self.rect.collidepoint(event.pos):
				for button in self.items:
					button.event(event)
	
	def scroll(self, factor):
		if 0 < -(self.offset + factor) < self.true_width - self.rect.width:
			self.offset += factor
		elif factor > 0:
			self.offset = 0
		elif factor < 0:
			self.offset = -(self.true_width - self.rect.width)
		
		self._adjust_item_rects()
	
	def _adjust_item_rects(self):
		total_item_widths = sum(item.rect.width for item in self.items)
		
		width, height = self.rect.size
		
		space = width - total_item_widths
		spacing = max(space / len(self.items), self.minimum_spacing)
		
		x, y = self.rect.topleft
		
		x = spacing // 2
		for item in self.items:
			item_width, item_height = item.rect.size
			
			item.rect.center = (self.offset + x + item_width // 2, y + height // 2)
			
			x += spacing + item_width
		
		self.true_width = x - (spacing // 2)

class Button(object):
	graphic = "menu/placeholder.png"
	action = None
	
	def __init__(self, menu, position=(0,0)):
		self.menu = menu
		
		x, y = position
		width, height = self.graphic.get_size()
		self.rect = Rect((x, y, width, height))
	
	def update(self):
		pass
		
	def draw(self, surface):
		width, height = self.graphic.get_size()
		
		#surface.fill((0, 0, 0), self.rect)
		surface.blit(self.graphic, self.rect.topleft)
	
	def event(self, event):
		if event.type == pygame.MOUSEBUTTONDOWN:
			if self.rect.collidepoint(event.pos):
				self.action()
	
	def action(self):
		self.menu.menu(self.name)

request_replace(Button)

class InputCancelled(Exception):
	pass

class TextEntry(object):
	try:
		font = pygame.font.Font(None, 8)
	except:
		font = None
	
	def __init__(self, prompt, content="", function=None, font=None, cursor=None, width=None):
		self.prompt = prompt
		self.content = content
		self.function = function
		
		if font is not None:
			self.font = font
		
		if cursor is None:
			self.cursor = len(content)
		else:
			self.cursor = cursor
		
		self.done = False
		
		if width is None:
			width = self.font.size("%s: " % self.prompt)[0] + 150
		
		self.text_size = self.font.get_height()
		self.surface = pygame.surface.Surface((width, self.text_size + 6))
		self.rect = pygame.Rect(0, 0, *self.surface.get_size())
	
	def draw(self, surface):	
		area = self.rect
		area.center = surface.get_rect().center
		pygame.draw.rect(surface, (0, 0, 0), area, 0)
		pygame.draw.rect(surface, (255, 255, 255), area, 1)
		oldclip = surface.get_clip()
		surface.set_clip(area.inflate(-4, -4))
			
		text = self.font.render("%s: %s" % (self.prompt, self.content), 1, (255, 255, 255), (0, 0, 0))
		cursor_x = self.font.size("%s: %s" % (self.prompt, self.content[:self.cursor]))[0]
		pygame.draw.line(text, (255, 255, 255), (cursor_x, 0), (cursor_x, self.text_size))
		surface.blit(text, area.move(5, 4))
		
		surface.set_clip(oldclip)
	
	def input(self, surface):
		while not self.done:
			self.draw(surface)
			pygame.display.update()
			
			event = pygame.event.wait()
			
			if event.type == pygame.QUIT:
				raise InputCancelled
				
			if event.type == pygame.KEYDOWN:		
				if event.key == pygame.K_BACKSPACE:
					if self.cursor > 0:
						self.content = "%s%s" % (self.content[:self.cursor-1], self.content[self.cursor:])
						self.cursor -= 1
				elif event.key == pygame.K_DELETE:
					if self.cursor < len(self.content):
						self.content = "%s%s" % (self.content[:self.cursor], self.content[self.cursor+1:])
				elif event.key == pygame.K_RIGHT:
					self.cursor = min(len(self.content), self.cursor+1)
				elif event.key == pygame.K_LEFT:
					self.cursor = max(0, self.cursor-1)
				elif event.key == pygame.K_RETURN:
					self.done = True
				elif event.key == pygame.K_ESCAPE:
					raise InputCancelled
				elif event.unicode:
					self.content = "%s%s%s" % (self.content[:self.cursor], event.unicode, self.content[self.cursor:])
					self.cursor += 1
			
		return self.content

	def event(self, event):
		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_BACKSPACE:
				self.content = self.content[:-1]
			elif event.key == pygame.K_RETURN:
				self.done = True
				self.function(self.content)
			elif event.unicode:
				self.content += event.unicode
			else:
				return False
			
			return True
		else:
			return False
